<!DOCTYPE html>
<html>
<head>
    <title>Optical System Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #fff;
        }
    </style>
</head>
<body>
    <canvas id="opticalSystemCanvas" width="750" height="450"></canvas>
    <script>
        const canvas = document.getElementById('opticalSystemCanvas');
        const ctx = canvas.getContext('2d');

        // Drawing parameters
        const scale = 8;
        const origin = { x: 150, y: 220 };
        const axisY = origin.y;
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 1.5;
        ctx.font = '20px serif';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';

        // Helper function to draw an arrow
        function drawArrow(x1, y1, x2, y2, headLength = 8) {
            const dx = x2 - x1;
            const dy = y2 - y1;
            const angle = Math.atan2(dy, dx);
            ctx.beginPath();
            ctx.moveTo(x1, y1);
            ctx.lineTo(x2, y2);
            ctx.lineTo(x2 - headLength * Math.cos(angle - Math.PI / 6), y2 - headLength * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(x2, y2);
            ctx.lineTo(x2 - headLength * Math.cos(angle + Math.PI / 6), y2 - headLength * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
        }

        // Helper function to draw a dimension line with T-bars
        function drawDimLineT(x1, y1, x2, y2, label, labelOffset = 15) {
            ctx.beginPath();
            ctx.moveTo(x1, y1);
            ctx.lineTo(x2, y2);
            // T-bars
            ctx.moveTo(x1, y1 - 5);
            ctx.lineTo(x1, y1 + 5);
            ctx.moveTo(x2, y2 - 5);
            ctx.lineTo(x2, y2 + 5);
            ctx.stroke();

            // Label
            ctx.save();
            ctx.translate((x1 + x2) / 2, y1 - labelOffset);
            ctx.fillText(label, 0, 0);
            ctx.restore();
        }
        
        // Helper function to draw a dimension line with arrows
        function drawDimLineArrow(x1, y1, x2, y2, label, labelOffset = {x: 0, y: 0}, isVertical = false) {
             const headLength = 8;
             ctx.beginPath();
             ctx.moveTo(x1, y1);
             ctx.lineTo(x2, y2);
             ctx.stroke();

            if(isVertical){
                // Top arrow
                let angle1 = Math.PI / 2;
                ctx.moveTo(x1, y1);
                ctx.lineTo(x1 - headLength * Math.cos(angle1 - Math.PI / 6), y1 - headLength * Math.sin(angle1 - Math.PI / 6));
                ctx.moveTo(x1, y1);
                ctx.lineTo(x1 - headLength * Math.cos(angle1 + Math.PI / 6), y1 - headLength * Math.sin(angle1 + Math.PI / 6));
                
                // Bottom arrow
                let angle2 = -Math.PI / 2;
                ctx.moveTo(x2, y2);
                ctx.lineTo(x2 - headLength * Math.cos(angle2 - Math.PI / 6), y2 - headLength * Math.sin(angle2 - Math.PI / 6));
                ctx.moveTo(x2, y2);
                ctx.lineTo(x2 - headLength * Math.cos(angle2 + Math.PI / 6), y2 - headLength * Math.sin(angle2 + Math.PI / 6));

            } else {
                 // Left arrow
                let angle1 = Math.PI;
                ctx.moveTo(x1, y1);
                ctx.lineTo(x1 - headLength * Math.cos(angle1 - Math.PI / 6), y1 - headLength * Math.sin(angle1 - Math.PI / 6));
                ctx.moveTo(x1, y1);
                ctx.lineTo(x1 - headLength * Math.cos(angle1 + Math.PI / 6), y1 - headLength * Math.sin(angle1 + Math.PI / 6));
                
                // Right arrow
                let angle2 = 0;
                ctx.moveTo(x2, y2);
                ctx.lineTo(x2 - headLength * Math.cos(angle2 - Math.PI / 6), y2 - headLength * Math.sin(angle2 - Math.PI / 6));
                ctx.moveTo(x2, y2);
                ctx.lineTo(x2 - headLength * Math.cos(angle2 + Math.PI / 6), y2 - headLength * Math.sin(angle2 + Math.PI / 6));
            }
            ctx.stroke();

            // Label
            ctx.fillText(label, (x1 + x2) / 2 + labelOffset.x, (y1 + y2) / 2 + labelOffset.y);
        }

        // 1. Draw Principal Axis
        ctx.beginPath();
        ctx.moveTo(10, axisY);
        ctx.lineTo(canvas.width - 10, axisY);
        ctx.stroke();

        // 2. Draw Prism
        const prismLeg = 6 * scale;
        const prismX_start = origin.x;
        const prismX_end = prismX_start + prismLeg;
        const prismY_bottom = axisY + prismLeg;
        
        ctx.beginPath();
        ctx.moveTo(prismX_start, axisY);
        ctx.lineTo(prismX_end, axisY);
        ctx.lineTo(prismX_end, prismY_bottom);
        ctx.closePath();
        ctx.stroke();

        // Angle marker
        ctx.beginPath();
        ctx.arc(prismX_start, axisY, 20, 0, -Math.PI / 4, true);
        ctx.stroke();
        ctx.fillText('45°', prismX_start + 25, axisY - 15);
        
        // Prism height dimension (as shown in diagram)
        const prismHeightDimX = prismX_end + 15;
        drawDimLineArrow(prismHeightDimX, axisY - 3*scale, prismHeightDimX, axisY + 3*scale, '6cm', {x: 35, y:0}, true);


        // 3. Draw Object
        const objLength = 1 * scale;
        const objHeight = 6 * scale;
        const objX = origin.x;
        const objY = axisY - objHeight;
        
        drawArrow(objX, objY, objX + objLength, objY);
        ctx.fillText('物', objX - 30, objY);

        // Object dimensions
        drawDimLineT(objX, objY - 10, objX + objLength, objY - 10, '1cm', 10);
        drawDimLineArrow(objX, objY, objX, axisY, '6cm', {x: -25, y:0}, true);

        // 4. Draw Lenses
        const lensHeight = 70;
        // Convex Lens
        const convexLensX = prismX_end + 10 * scale;
        ctx.beginPath();
        ctx.moveTo(convexLensX, axisY - lensHeight);
        ctx.lineTo(convexLensX, axisY + lensHeight);
        ctx.stroke();
        // Top arrow
        drawArrow(convexLensX, axisY - lensHeight - 10, convexLensX, axisY - lensHeight);
        // Bottom arrow
        drawArrow(convexLensX, axisY + lensHeight + 10, convexLensX, axisY + lensHeight);
        ctx.fillText('f\u51F8=20cm', convexLensX, axisY - lensHeight - 25);

        // Concave Lens
        const concaveLensX = convexLensX + 5 * scale;
        ctx.beginPath();
        ctx.moveTo(concaveLensX, axisY - lensHeight);
        ctx.lineTo(concaveLensX, axisY + lensHeight);
        ctx.stroke();
        // Top V-shape
        ctx.beginPath();
        ctx.moveTo(concaveLensX - 6, axisY - lensHeight + 6);
        ctx.lineTo(concaveLensX, axisY - lensHeight);
        ctx.lineTo(concaveLensX + 6, axisY - lensHeight + 6);
        ctx.stroke();
        // Bottom V-shape
        ctx.beginPath();
        ctx.moveTo(concaveLensX - 6, axisY + lensHeight - 6);
        ctx.lineTo(concaveLensX, axisY + lensHeight);
        ctx.lineTo(concaveLensX + 6, axisY + lensHeight - 6);
        ctx.stroke();
        ctx.fillText('f\u51F9=-10cm', concaveLensX + 10, axisY - lensHeight - 25);

        // 5. Draw bottom distance dimensions
        const dimY = axisY + 120;
        // 10cm distance
        drawDimLineArrow(prismX_end, dimY, convexLensX, dimY, '10cm', {x:0, y: -15});
        // 5cm distance
        drawDimLineArrow(convexLensX, dimY, concaveLensX, dimY, '5cm', {x:0, y: -15});
    </script>
</body>
</html>